﻿using System;
using System.Collections.Generic;
using System.Collections;
using Layers;

namespace Gaming
{

    public static class Suits
    {
        public static int Clubs       = 0,
        public static int Diamonds    = 1,
        public static int Hearts      = 2,
        public static int Spades
    }

    public enum Ranks
    {
        Two=2,
        Three=3,
        Four=4,
        Five=5,
        Six=6,
        Seven=7,
        Eight=8,
        Nine=9,
        Ten=10,
        Jack=11,
        Queen=12,
        King=13,
        Ace=14
    }

    /// <summary>
    /// One single card.
    /// 
    /// Card is represented by the code, which is bit array
    /// ssss rrrr, 
    /// here:
    ///  ssss - 4 bit for card suit (0..3)
    ///  rrrr - 4 bit for card rank (2..14)
    /// </summary>
    
    public struct Card:IComparable<Card>,IEquatable<Card>
    {
        #region Fields
        internal int _code;
        #endregion

        #region Card Naming
        private static string[] _rankChar = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A" };
        private static string[] _rankName = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace","(err)","(err)" };
         private static string[] _suiteChar = new string[] { "c", "d", "h", "s" };
        #endregion

        #region Properties
        
        public int Code { get { return _code; } set { _code = value; } }

        public int Suit { get{ return (_code>>4); } }
        
        public int Rank { get{ return (_code&0xF); } }

        #endregion

        #region Constructors
        public Card(int code) { _code = code; }

        public Card(int suit, int rank) { _code = (suit << 4) | rank; }

        public static Card FromCode(int code) 
        {
           // if (!IsValidCode(code))
            //    throw new InvalidOperationException();
            return new Card(code); 
        }

        public static bool IsValidCode(int code)
        {
            int suit = code>>4;
            int rank = code&0xF;

            if (suit >= 0 && suit <= 3
                 && rank >= (int)Ranks.Two && rank <= (int)Ranks.Ace)
                return true;
            return false;
        }

        /// <summary>
        /// Parses card
        /// samples: As, Qc
        /// </summary>
        /// <param name="input"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        public static Card Parse(string input, ref int pos)
        {
            string tok;
            
            tok = input.Substring(pos,1);
            int rank = Card.ParseRank(tok);
            if (rank < 0)
                return Card.Empty;
            pos++;

            tok = input.Substring(pos, 1);
            int suit = Card.ParseSuit(tok);
            if (rank < 0)
                return Card.Empty;
            pos++;

            return FromSuitRank(suit, rank);
        }

        public static Card Min = Card.FromSuitRank(0, (int)Ranks.Two);
        public static Card Max = Card.FromSuitRank(3, (int)Ranks.Ace);

        public static Card Empty = Card.FromCode(0);

        public static bool operator==(Card left, Card right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(Card left, Card right)
        {
            return !left.Equals(right);
        }

        internal static int ParseRank(string rank)
        {
            for (int i = 0; i < _rankChar.Length; i++)
                if (rank.Equals(_rankChar[i]))
                    return i;
            return -1;
        }

        internal static int ParseSuit(string suit)
        {
            for (int i = 0; i < _suiteChar.Length; i++)
                if (suit.Equals(_suiteChar[i]))
                    return i;
            return -1;
        }

        public static string RankChar(int rank)
        {
            return _rankChar[rank];
        }

        public static Card FromSuitRank(int suit, int rank) { return new Card(suit, rank); }
        #endregion
        
        #region Hash, Debug
        public override string ToString()
        {
            return _rankChar[Rank] + _suiteChar[Suit];
        }

        public override int GetHashCode()
        {
            return _code;
        }
        #endregion

        #region IComparable<Card> Members


        /// <summary>
        /// Orders cards so that higher Rank are first. 
        /// With equal ranks cards are ordered by suits.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(Card other)
        {
            int r = other.Rank - Rank;
            if (r != 0)
                return r;
            return other.Suit - Suit;
        }

        #endregion
    
        #region IEquatable<Card> Members

        public bool  Equals(Card other)
        {
 	        return this.Code==other.Code;
        }

        #endregion
}

    

    
    


    public class Calculator
    {
        IDictionary<CardSet, int> _rating = new Dictionary<CardSet, int>();

        public void Update(TableGenerator Table)
        {
        }
    }

}